/*
 * Utilities.c
 *      Author: dephille
 */

#include "Utilities.h"


/**
 * Splits a string into several substrings.
 *
 * @param	string		The string to split.
 * @param	delimiter	The string by which the substrings are delimited.
 * @param	A GList containing the substrings or NULL if failed.
 */
static GList*	PC_Util_Split(const gchar* string, const gchar* delimiter) {
	GList*			retList;		// Clean-up: No
	unsigned int	delimiterLen;	// Clean-up: No
	const gchar*	start;			// Clean-up: No
	const gchar*	end;			// Clean-up: No
	gchar*			curPart;		// Clean-up: No

	// Check input:
	if (!string) {
		purple_debug_warning("PidginCote", "PC_Util_Split: Missing 'string' parameter.\r\n");
		return NULL;
	} else if (!delimiter) {
		return g_list_prepend(NULL, g_strdup(string));
	}

	// Detach parts:
	delimiterLen = strlen(delimiter);
	start = string;
	retList = NULL;
	while (start) {
		// Find end:
		end = g_strstr_len(start, -1, delimiter);

		// Detach part:
		if (end) {
			curPart = g_strndup(start, (end-start));
		} else {
			curPart = g_strdup(start);
		}

		// Add to list:
		retList = g_list_prepend(retList, curPart);

		// Next part:
		if (end) {
			start = end + delimiterLen;
		} else {
			start = NULL;
		}
	}

	// Return list:
	return retList;
}


/**
 * Builds a UNIX timestamp from the given date/time information.
 *
 * @param	year	The year.
 * @param	month	The month.
 * @param	day		The day.
 * @param	hour	The hour.
 * @param	minute	The minute.
 * @param	second	The second.
 * @return	The generated unix timestamp.
 */
static time_t PC_Util_BuildTime(unsigned int year, unsigned int month, unsigned int day, unsigned int hour, unsigned int minute, unsigned int second) {
	time_t retTime;
	long tzOffset;

	// Filter out the local timezone by comparing the year 2000:
	tzOffset = purple_time_build(2000,1,1,0,0,0) - 946684800;

	// Build the UNIX timestamp:
	retTime = purple_time_build(year, month, day, hour, minute, second);
	retTime -= tzOffset;

	// Return result:
	return retTime;
}



/**
 * Compares the first 'len' characters of two strings. If len 0 is used, this function is identical to the standard strcmp0.
 *
 * @param str1 First string.
 * @param str2 Second string.
 * @param len Amount of characters to compare. 0 acts as strcmp0
 * @return See strcmp0.
 */
static int PC_Util_Strncmp0(const gchar* str1, const gchar* str2, unsigned long len) {
	unsigned long curIndex;		// Clean-up: No

	// Both strings are identical:
	if (str1 == str2) {
		return 0;

	// str1 is null:
	} else if (!str1) {
		return -1;

	// str2 is null:
	} else if (!str2) {
		return 1;

	// len is 0 (use strcmp0):
	} else if (len <= 0) {
		return g_strcmp0(str1, str2);

	// Compare character by character:
	} else {

		// Skip all identical characters:
		curIndex = 0;
		while ((curIndex < (len - 1)) && (str1[curIndex] != '\0') && (str2[curIndex] != '\0') && (str1[curIndex] == str2[curIndex])) {
			curIndex++;
		}

		// str1 < str2:
		if (str1[curIndex] < str2[curIndex]) {
			return -1;

		// str2 < str1
		} else if (str1[curIndex] < str2[curIndex]) {
			return 1;

		// str1 == str2
		} else {
			return 0;
		}
	}
}


/**
 * Loads the last modification time of a given file.
 *
 * @param	fileName	The filename for which to fetch the MTime from the filesystem.
 * @returns	A time_t object with the MTime of the given file.
 */
static time_t PC_Util_GetMTime(const gchar* fileName) {
	struct stat fileInfo;	// Clean-up: No

	// Check input:
	if(!fileName) {
		purple_debug_warning("PidginCote", "PC_Util_GetMTime: Missing 'fileName' parameter.\r\n");
		return 0;
	}

	// Fetch fileInfo:
	if (g_stat(fileName, &fileInfo) != 0) {
		purple_debug_warning("PidginCote", "PC_Util_GetMTime: Unable to fetch fileInfo from %s\r\n", fileName);
		return 0;
	}

	// Return:
	return fileInfo.st_mtim.tv_sec;
}

/**
 * Gets the amount of miliseconds since the UNIX epoch.
 *
 * @returns	Amount of msec since the UNIX epoch.
 */
static gint64 PC_Util_GetMiliSeconds() {
	GTimeVal	retTime;	// Clean-up: No

	// Get time:
	g_get_current_time(&retTime);

	// Transform to int:
	return (retTime.tv_sec * 1000) + (retTime.tv_usec / 1000);
}

/**
 * Parses a PurpleAccount's username.
 * 	Currently, this function removes everything behind a slash.
 */
static gchar* PC_Util_ParseUsername(const gchar* username) {
	const gchar*	slashLoc;	// Clean-up: No
	gchar*			retString;	// Clean-up: No
	gchar*			tmp;		// Clean-up: Yes

	// Check input:
	if (!username) {
		purple_debug_warning("PidginCote", "PC_Util_ParseUsername: Missing 'username' parameter.\r\n");
		return NULL;
	}

	// To Lowercase:
	tmp = g_ascii_strdown(username, -1);

	// Find slash, if present:
	slashLoc = g_strstr_len(tmp, -1, "/");
	if (slashLoc) {
		retString = g_strndup(tmp, slashLoc - tmp);
		g_free(tmp);
	} else {
		retString = tmp;
	}

	// Return:
	return retString;
}
